﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Threading;
using System.Windows.Markup;
using System.Windows.Controls.Primitives;

namespace Invini.Training
{
    [ContentProperty("Content")]
    public class InstructAction : TrainingActionBase
    {
        public PathComponentsCollection Element
        {
            get;
            set;
        }
        public object Content
        {
            get;
            set;
        }
        public TrainingInfoPlacement Placement
        {
            get;
            set;
        }
        public double MaxWidth
        {
            get;
            set;
        }
        public double Width
        {
            get;
            set;
        }
        public TrainingInfoButton Button
        {
            get;
            set;
        }

        private Popup popup;

        public InstructAction()
        {
            this.Element = new PathComponentsCollection();
            this.MaxWidth = double.PositiveInfinity;
            this.Width = double.NaN;
        }
        public override void Execute()
        {
            if (this.Element == null)
            {
                this.onCompleted();
                return;
            }

            IEnumerable<object> objects = this.Element.FindElements();
            if (objects.Count() == 0)
            {
                this.onCompleted();
                return;
            }

            TrainingInfo info = new TrainingInfo();
            info.Button = this.Button;
            info.Content = this.Content;
            info.Placement = this.Placement;

            this.popup = new Popup();

            TrainingOptions.SetIgnore(this.popup, true);

            this.popup.PlacementTarget = objects.First() as UIElement;
            if(this.popup.PlacementTarget == null)
            {
                this.onCompleted();
                return;
            }

            this.popup.Placement= PlacementMode.Custom;
            this.popup.CustomPopupPlacementCallback = this.popupPosition;
            this.popup.AllowsTransparency = true;
            this.popup.SnapsToDevicePixels = true;
            //this.popup.PopupAnimation = PopupAnimation.Fade;
            this.popup.Width = this.Width;
            this.popup.MaxWidth = this.MaxWidth;
            this.popup.Child = info;
            this.popup.StaysOpen = true;

            Window window = Window.GetWindow(this.popup.PlacementTarget);
            window.Activated += this.windowStateChanged;
            window.Deactivated += this.windowStateChanged;
            window.StateChanged += this.windowStateChanged;

            FrameworkElement target = this.popup.PlacementTarget as FrameworkElement;
            if (target != null)
                target.BringIntoView();

            this.popup.IsOpen = window.IsActive && (window.WindowState != WindowState.Minimized);

            if (this.Button == TrainingInfoButton.None)
                this.onCompleted();
            else
                info.ButtonClicked += this.info_ButtonClicked;
       }

        private void windowStateChanged(object sender, EventArgs e)
        {
            if (this.popup == null)
                return;

            Window window = sender as Window;
            if (window == null)
                return;

            this.popup.IsOpen = window.IsActive && (window.WindowState != WindowState.Minimized);

        }
        public override void Clear()
        {
            base.Clear();

            if(this.popup != null)
            {
                this.popup.IsOpen = false;
                this.popup.PlacementTarget = null;
                this.popup = null;
            }
        }

        private void info_ButtonClicked(TrainingInfo info, TrainingInfoButtonClickedEventArgs e)
        {
            this.Clear();
            this.onCompleted();
        }
        private CustomPopupPlacement[] popupPosition(Size popupSize, Size targetSize, Point offset)
        {
            double translation = 10.0;

            Point point = new Point();
            switch(this.Placement)
            {
                case TrainingInfoPlacement.Left:
                    point = new Point(-popupSize.Width + translation, (targetSize.Height - popupSize.Height) / 2.0);
                    break;
                case TrainingInfoPlacement.Top:
                    point = new Point((targetSize.Width - popupSize.Width) / 2.0, -popupSize.Height + translation);
                    break;
                case TrainingInfoPlacement.Right:
                    point = new Point(targetSize.Width - translation, (targetSize.Height - popupSize.Height) / 2.0);
                    break;
                case TrainingInfoPlacement.Bottom:
                    point = new Point((targetSize.Width - popupSize.Width) / 2.0, targetSize.Height - translation);
                    break;
                case TrainingInfoPlacement.Center:
                    point = new Point((targetSize.Width - popupSize.Width) / 2.0, (targetSize.Height - popupSize.Height) / 2.0);
                    break;
            }

            return new CustomPopupPlacement[] { new CustomPopupPlacement(point, PopupPrimaryAxis.None) };
        }
    }
}
